package com.hjlsoft.aftp.data.fs;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Date;

import com.hjlsoft.aftp.common.MD5Util;
import com.hjlsoft.aftp.common.TimeUtil;
import com.hjlsoft.aftp.data.DataHandle;
import com.hjlsoft.aftp.data.DataMeta;
import com.hjlsoft.aftp.data.DataMetaStatusEnum;
import com.hjlsoft.aftp.data.DataStoreService;
import com.hjlsoft.aftp.token.Token;

public class FsDataStoreService implements DataStoreService {

	private File basePath;

	private FsDataMetaHandle dataMetaHandle;

	public FsDataStoreService(String basePath) {
		super();
		this.basePath = new File(basePath);
	}

	public void init() {
		basePath.mkdirs();
		dataMetaHandle = new FsDataMetaHandle(basePath);
	}

	public DataHandle create(Token token, DataMeta dataMeta) throws IOException {
		File file = getDataFile(token.getId());
		return new FsDataHandle(new RandomAccessFile(file, "rw"), dataMetaHandle, token, dataMeta);
	}

	public String getDataMD5(Token token) throws IOException {
		File file = getDataFile(token.getId());
		return MD5Util.getFileMD5String(file);
	}

	public boolean commit(Token token) throws IOException {
		File file = getDataFile(token.getId());

		DataMeta dataMeta = dataMetaHandle.get(token.getId());
		if (dataMeta == null) {
			throw new IllegalStateException("data meta not found!");
		}
		if(file.renameTo(new File(basePath, token.getId() + ".commit"))) {
			dataMeta.setStatus(DataMetaStatusEnum.COMMITTED.getValue());
			dataMetaHandle.save(dataMeta);
			return true;
		} else {
			return false;
		}
			
	}

	public DataMeta getDataMeta(String id) throws IOException {
		return dataMetaHandle.get(id);
	}

	public void delete(String id) throws IOException {
		String nowString = TimeUtil.format(new Date(), "yyyy_MM_dd_HH_mm_ss");
		File metaFile = dataMetaHandle.getMetaFile(id);
		metaFile.renameTo(new File(basePath, id + ".meta." + nowString + ".deleted"));

		File file = getDataFile(id);
		file.renameTo(new File(basePath, id + "." + nowString + ".deleted"));
	}

	protected File getDataFile(String id) {
		return new File(basePath, id + ".tmp");
	}

}
